package com.zlc.common.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.lettuce.LettuceConnection;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @description: redis相关的工具类
 * @author: zl
 */
@Slf4j
@Component
public class RedisUtils {

    private static RedisTemplate<String, Object> redisTemplate;

    @Autowired
    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        RedisUtils.redisTemplate = redisTemplate;
    }

    public static boolean set(String key,Object o,Long timeSeconds) {
        try {
            String value = JsonHelper.toJson(o);
            if(o instanceof CharSequence) {
                value = (String)o;
            }
            redisTemplate.opsForValue().set(key,value,timeSeconds, TimeUnit.SECONDS);
            return true;
        } catch (Exception e){
            log.info("redis 异常,e : {}",e.getMessage());
            return false;
        }
    }

    public static boolean setAdd(String key,Object o){
        try {
            String value = JsonHelper.toJson(o);
            if(o instanceof CharSequence) {
                value = (String)o;
            }
            redisTemplate.opsForSet().add(key,value);
            return true;
        } catch (Exception e){
            log.info("redis 异常,e : {}",e.getMessage());
            return false;
        }
    }

    public static DataType getType(String key){
        try {
            return redisTemplate.type(key);
        } catch (Exception e){
            log.info("redis 获取类型异常,e : {}",e.getMessage());
            return null;
        }
    }

    public static boolean removeSet(String key,List<Object> values){
        try {
            redisTemplate.opsForSet().remove(key,values);
            return true;
        } catch (Exception e){
            log.info("redis 异常,e : {}",e.getMessage());
            return false;
        }
    }

    public static Set<Object> setGet(String key){
        try {
            return redisTemplate.opsForSet().members(key);
        }catch (Exception e){
            e.printStackTrace();
        }
        return new HashSet<>();
    }

    public static Set<Object> setGets(List<String> keys){
        Set<Object> ret = new HashSet<>();
        List<Object> results = redisTemplate.executePipelined(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                LettuceConnection lettuceConnection = (LettuceConnection) connection;

                return null;
            }
        });
        for (Object result : results) {
            Set<Object> members = (Set<Object>) result;
            // 处理每个Set的结果
            ret.addAll(members);
        }
        return ret;
    }

    public static boolean set(String key,Object o) {
        try {
            String value = JsonHelper.toJson(o);
            if(o instanceof CharSequence) {
                value = (String)o;
            }
            redisTemplate.opsForValue().set(key,value);
            return true;
        } catch (Exception e){
            log.info("redis 存异常,e : {}",e.getMessage());
            return false;
        }
    }


    public static Boolean delete(String key){
        try {
            return redisTemplate.delete(key);
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }


    public static <R> R get(String key,Class<R> clazz) {
        try {
            Object value = redisTemplate.opsForValue().get(key);
            return JsonHelper.jsonToObject((String)value,clazz);
        } catch (Exception e){
            log.error("REDIS 获取值异常,e:{},key:{}",e.getMessage(),key);
            return null;
        }
    }

    public static Set<String> keys(String prefix) {
        Set<String> keys = new HashSet<>();
        redisTemplate.execute((RedisCallback<Object>) connection -> {
            Cursor<byte[]> cursor = connection.scan(
                    ScanOptions.scanOptions()
                            .match(prefix + "*")
                            .count(1000)
                            .build()
            );
            while (cursor.hasNext()) {
                keys.add(new String(cursor.next()));
            }
            try {
                cursor.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        });
        return keys;
    }

    public static String get(String key){
        try {
            Object value = redisTemplate.opsForValue().get(key);
            return (String) value;
        } catch (Exception e){
            log.error("REDIS 获取值异常,e:{},key:{}",e.getMessage(),key);
            return null;
        }
    }

    public static List<Object> multiGet(Set<String> keys){
        try {
            return redisTemplate.opsForValue().multiGet(keys);
        } catch (Exception e){
            log.error("REDIS 获取值异常,e:{},key:{}",e.getMessage(),keys);
            return null;
        }
    }

    public static HashOperations<String, Object, Object> hashOperate(){
        return redisTemplate.opsForHash();
    }

    public static ListOperations<String, Object> listOperate(){
        return redisTemplate.opsForList();
    }

    public static SetOperations<String, Object> setOperate(){
        return redisTemplate.opsForSet();
    }

    public static ZSetOperations<String, Object> zSetOperate(){
        return redisTemplate.opsForZSet();
    }

    public static ValueOperations<String, Object> valueOperate(){
        return redisTemplate.opsForValue();
    }

}
